package db

import (
	"errors"
	"hr/api/dto"

	"github.com/spf13/cast"
	"gorm.io/gorm"
)

// NoInsureApproval 保险断缴申请
type NoInsureApproval struct {
	AppModel
	UserID         string `gorm:"size:64" json:"user_id"`
	Reason         string `json:"reason"`
	CreateBy       string `gorm:"size:128" json:"createBy"`        // 创建人
	UpdateBy       string `gorm:"size:128" json:"updateBy"`        // 更新人
	Remark         string `gorm:"size:255" json:"remark"`          //备注
	OrderStatus    string `gorm:"size:64;" json:"order_status"`    // 申请状态 1保存、2提交
	ApprovalStatus string `gorm:"size:64;" json:"approval_status"` // 是否同意 1是2否
	RefuseReason   string `json:"refuseReason"`
	Types          string `gorm:"size:64;" json:"types"` //类别用,号分开：1养老保险 2失业保险 3医疗保险 4工伤保险 5生育保险
	Pass           string `gorm:"size:64;" json:"pass"`  //通过类别
}

func (u *NoInsureApproval) TableName() string {
	return "no_insure_approval"
}

type NoInsureApprovalName struct {
	NoInsureApproval
	UserName string `json:"user_name"`
}

type NoInsureApprovalPageModel struct {
	Total    int64                  `json:"total"`
	Result   []NoInsureApprovalName `json:"result"`
	PageNo   int                    `json:"pageNo"`
	PageSize int                    `json:"pageSize"`
}

func GetNoInsureApprovalPaging(pagination dto.Pagination, name string, userId uint, from string) (NoInsureApprovalPageModel, error) {
	user := GetUserById(userId)
	role := GetRoleById(user.RoleID)
	result := NoInsureApprovalPageModel{
		Total:    0,
		Result:   make([]NoInsureApprovalName, 0),
		PageNo:   pagination.PageNo,
		PageSize: pagination.PageSize,
	}
	offset := (pagination.PageNo - 1) * pagination.PageSize
	dbs := GetInstance().Select("no_insure_approval.*,concat(IFNULL(user.name,''),'(',user.nick_name,')') as user_name").Joins("left join user on no_insure_approval.create_by = user.id")

	if from == "1" && role.Code == "small_captain" {
		dbs = dbs.Where("user.dept_id=?", user.DeptID).Where("no_insure_approval.approval_status='3'").Order("no_insure_approval.created_at desc")
	} else {
		if role.Code == "supper" {
			dbs = dbs.Where("no_insure_approval.approval_status!='3'").Order("no_insure_approval.created_at desc")
		} else {
			dbs = dbs.Where("no_insure_approval.create_by = ?", userId).Order("no_insure_approval.created_at desc")
		}
	}

	if err := dbs.Offset(offset).Limit(pagination.PageSize).Find(&result.Result).Error; err != nil {
		return result, err
	}
	if err := dbs.Offset(-1).Limit(-1).Count(&result.Total).Error; err != nil {
		return result, err
	}
	return result, nil
}

func GetNoInsureApproval(p map[string]interface{}, extra ...interface{}) (NoInsureApproval, error, string) {
	f := NoInsureApproval{}
	queryDb := GetInstance().Where(p).First(&f)
	if len(extra) > 0 {
		queryDb = queryDb.Where(extra)
	}
	err := queryDb.Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return f, errors.New("查无记录"), "0"
		}
		return f, errors.New(err.Error()), "1"
	}
	return f, nil, "2"
}

func CreateNoInsureApproval(p NoInsureApproval, userId string) (NoInsureApproval, error) {
	approval := p.ApprovalStatus
	if p.OrderStatus == "2" {
		user := GetUserById(cast.ToUint(userId))
		isCaptain := HasSmallCaptain(user.DeptID)
		if isCaptain {
			approval = "3"
		}
	}
	d := NoInsureApproval{
		UserID:         p.UserID,
		Reason:         p.Reason,
		CreateBy:       userId,
		Remark:         p.Remark,
		OrderStatus:    p.OrderStatus,
		ApprovalStatus: approval,
		RefuseReason:   p.RefuseReason,
		Types:          p.Types,
	}
	if err := GetInstance().Create(&d).Error; err != nil {
		return d, errors.New("创建失败")
	}
	return d, nil
}

func UpdateNoInsureApproval(id uint, p NoInsureApproval, user string) (NoInsureApproval, error) {
	f := NoInsureApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(NoInsureApproval{
		UserID:         p.UserID,
		Reason:         p.Reason,
		UpdateBy:       user,
		Remark:         p.Remark,
		OrderStatus:    p.OrderStatus,
		ApprovalStatus: p.ApprovalStatus,
		RefuseReason:   p.RefuseReason,
		Types:          p.Types,
	}).Updates(map[string]interface{}{
		"id": id,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func DeleteNoInsureApproval(id uint) (NoInsureApproval, error) {
	f := NoInsureApproval{}
	err := GetInstance().Unscoped().Where("id = ?", id).Delete(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func UpdateNoInsureApprovalOrderStatus(id uint, status string, userId uint) (NoInsureApproval, error) {
	approval := ""
	if status == "2" {
		user := GetUserById(userId)
		isCaptain := HasSmallCaptain(user.DeptID)
		if isCaptain {
			approval = "3"
		}
	}
	f := NoInsureApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	err := GetInstance().Model(&f).Updates(map[string]interface{}{
		"order_status":    status,
		"approval_status": approval,
	}).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}

func UpdateNoInsureApprovalApprovalStatus(p dto.InsureRequest, id uint) (NoInsureApproval, error) {
	f := NoInsureApproval{
		AppModel: AppModel{
			ID: id,
		},
	}
	data := make(map[string]interface{})
	data["refuse_reason"] = p.RefuseReason
	data["approval_status"] = p.ApprovalStatus
	data["pass"] = p.Pass
	err := GetInstance().Model(&f).Updates(data).Scan(&f).Error
	if err != nil {
		return f, err
	}
	return f, nil
}
